home *** CD-ROM | disk | FTP | other *** search
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
-
- static int copy_files ();
- static long file_len ();
- static int do_copy ();
- long atol ();
-
- #define SIZE_BUFFER 1024
- #define OK 0
- #define NOT_OK -1
- #define min(a,b) ((a)<(b)?a:b)
- #define IFTESTING
- #ifdef IFTESTING
- /*
- * To test the code compile with parameter -DTESTING and execute
- * a.out filename newlength
- */
-
- main (int argc, char **argv)
- {
- printf ("%2d", truncate_file (argv[1], atol (argv[2])));
- }
- #endif
-
- truncate_file(char *path, long len)
- {
- int infile, tmp_file; /* input file */
- int ret = 0;
- char tf_name[L_tmpnam];
- if (len < 0)
- ret = -10;
- else if (len == 0)
- ret = truncate_to_zero (path);
- else if ((infile = open(path, O_RDONLY, 0)) < 0)
- ret = -1;
- else if (file_len (infile) <= len)
- {
- close (infile);
- ret = -3;
- }
- else
- {
- tmpnam (tf_name);
- tmp_file = open (tf_name, O_RDWR | O_CREAT, 0666);
- ret = copy_file (infile, tmp_file, path, len);
- unlink (tf_name);
- }
- return ret;
- }
- /*
- * file_len () returns the length of file, in bytes
- */
-
- static long file_len (infile)
- {
- struct stat file_status;
-
- fstat (infile, &file_status);
- return file_status.st_size;
- }
-
- /*
- * copy_file () copies in_file to tmp_file then back to
- * in_file, truncating to len bytes in the process
- */
-
- copy_file (int infile, int tmp_file, char *path, long len)
- {
- int ret = 0;
- if ((ret = do_copy (infile, tmp_file, len)) == 0)
- {
- close (infile);
- lseek (tmp_file, 0L, SEEK_SET);
- if (( infile = open (path, O_WRONLY | O_TRUNC, 0666)) < 0)
- ret = -12;
- else
- ret = do_copy (tmp_file, infile, len);
- }
- return ret;
- }
- /*
- * do_copy () copies len bytes from infile to tmp_file
- */
- static int do_copy (int infile, int tmp_file, long len)
- {
- int to_read, to_write, ret = 0;
- char buffer [SIZE_BUFFER];
-
- do
- {
- to_read = (int) (min ((long) SIZE_BUFFER, len));
- if ((to_write = read (infile, buffer, to_read)) < to_read)
- {
- ret = -4;
- break;
- }
- if (write (tmp_file, buffer, to_write) < to_write)
- {
- ret = -5;
- break;
- }
- } while (len -= to_write);
- return ret;
- }
- /*
- * truncate_to_zero () opens the file *path with the
- * option O_Trunc.
- */
- truncate_to_zero (char *path)
- {
- int ret = OK;
- int fd = open (path, O_WRONLY | O_TRUNC, 0666);
-
- if (fd < 0)
- ret = NOT_OK;
- close (fd);
- return ret;
- }
-
-